package com.lemeng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.lemeng.dao.CategoryReportMapper;
import com.lemeng.dao.OrderItemMapper;
import com.lemeng.dao.OrderMapper;
import com.lemeng.pojo.*;
import com.lemeng.service.*;
import com.lemeng.util.CacheKey;
import com.lemeng.util.IdWorker;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service(interfaceClass = CartService.class)
public class CartServiceImpl implements CartService {

    @Autowired
    RedisTemplate redisTemplate;
    @Reference
    SkuService skuService;
    @Reference
    CategoryService categoryService;
    @Autowired
    PreferentialService preferentialService;
    @Autowired
    IdWorker idWorker;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderItemMapper orderItemMapper;
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public void addCart(String username, String skuId, Integer num) {


        List<Map> mycarts = (List<Map>)redisTemplate.boundHashOps(CacheKey.CART_LIST).get(username);

        boolean flag = false;

        if (!CollectionUtils.isEmpty(mycarts)){//有购物车
            for (Map mycart : mycarts) {
                OrderItem orderItem =(OrderItem) mycart.get("orderItem");
                if (orderItem.getSkuId().equals(skuId)) {//说明有

                    flag = true;

                    int weight = orderItem.getWeight()/orderItem.getNum();//原来单个重量

                    //更新数量
                    orderItem.setNum(orderItem.getNum()+num);
                    if (orderItem.getNum()<=0){
                        mycarts.remove(mycart);
                        break;
                    }

                    orderItem.setMoney(orderItem.getNum()*orderItem.getPrice());

                    orderItem.setWeight(weight*orderItem.getNum());

                    break;

                }
            }
            if (!flag){
                mycarts.add(getNewInfo(skuId,num));
            }
        }else {//没有购物车
            mycarts = new ArrayList<>();
            mycarts.add(getNewInfo(skuId,num));
        }

        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,mycarts);
    }

    public HashMap getNewInfo(String skuId, Integer num){
        HashMap hashMap = new HashMap();

        hashMap.put("checked",true);

        OrderItem orderItem = new OrderItem();

        Sku sku = skuService.findById(skuId);


        //得到三级分类
        Category category3 = categoryService.findById(sku.getCategoryId());

        Category category2 = categoryService.findById(category3.getParentId());

        orderItem.setCategoryId3(sku.getCategoryId());
        orderItem.setCategoryId2(category2.getId());
        orderItem.setCategoryId1(category2.getParentId());

        orderItem.setSpuId(sku.getSpuId());
        orderItem.setSkuId(sku.getId());

        orderItem.setName(sku.getName());
        orderItem.setPrice(sku.getPrice());
        orderItem.setNum(num);
        orderItem.setMoney(num*sku.getPrice());

        orderItem.setImage(sku.getImage());

        if (sku.getWeight() == null){
            sku.setWeight(0);
        }
        orderItem.setWeight(sku.getWeight()*num);



        hashMap.put("orderItem",orderItem);
        hashMap.put("spec", JSONObject.parseObject(sku.getSpec()));

        return hashMap;
    }


    @Override
    public List<Map> findCart(String username) {
        List<Map> carts = (List<Map>)redisTemplate.boundHashOps(CacheKey.CART_LIST).get(username);


        for (Map cart : carts) {
            OrderItem orderItem = (OrderItem) cart.get("orderItem");
            Sku sku = skuService.findById(orderItem.getSkuId());
            orderItem.setPrice(sku.getPrice());//更新单价
            orderItem.setMoney(orderItem.getNum()*orderItem.getPrice());//更新总价
        }
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,carts);
        return carts;
    }

    @Override
    public void changeCheckedState(String username, String ids) {
        List<Map> cart = findCart(username);
        for (Map map : cart) {
            map.put("checked",false);
        }

        for (String skuId : ids.split(",")) {
            for (Map map : cart) {
                OrderItem orderItem =(OrderItem) map.get("orderItem");
                if (orderItem.getSkuId().equals(skuId)) {
                    map.put("checked",true);
                    break;
                }
            }
        }
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,cart);
    }

    @Override
    public void delAll(String username, String ids) {
        List<Map> cart = findCart(username);

        for (String skuId : ids.split(",")) {

            for (Map map : cart) {
                OrderItem orderItem =(OrderItem) map.get("orderItem");
                if (orderItem.getSkuId().equals(skuId)) {
                    cart.remove(map);
                    break;
                }
            }
        }
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,cart);
    }
    //传入所有购物车 返回选中购物车
    public List<Map> getCheckedCarts(List<Map> cart){
        ArrayList<Map> list = new ArrayList<>();
        for (Map map : cart) {
            if ((Boolean)map.get("checked")){
                list.add(map);
            }
        }
        return list;
    }

    @Override
    public Integer getMyPreMoney(String username) {
        List<Map> cart = findCart(username);

        List<Map> checkedCarts = getCheckedCarts(cart);

        HashMap<Integer, Integer> categoryMoney = new HashMap<>();
        for (Map map : checkedCarts) {
            OrderItem orderItem =(OrderItem) map.get("orderItem");
            if (categoryMoney.containsKey(orderItem.getCategoryId3())) {
                Integer oldMoney = categoryMoney.get(orderItem.getCategoryId3());
                categoryMoney.put(orderItem.getCategoryId3(),oldMoney+orderItem.getMoney());
            }else {
                categoryMoney.put(orderItem.getCategoryId3(),orderItem.getMoney());
            }
        }

        Integer preMoney = 0;

        for (Integer categoryId : categoryMoney.keySet()) {
            preMoney+=preferentialService.findCategoryPreMoney(categoryId,categoryMoney.get(categoryId));
        }
        return preMoney;
    }

    @Override
    @Transactional
    public Map<String, Object> submitOrder(String username,Order order) {
        List<Map> cart = findCart(username);
        //得到选中购物车列表
        List<Map> checkedCarts = getCheckedCarts(cart);

        int totalMoney = 0;
        int totalNum = 0;

        List<OrderItem> orderItems = new ArrayList<>();//当前选中购物车的orderItemList
        for (Map checkedCart : checkedCarts) {
            OrderItem orderItem = (OrderItem)checkedCart.get("orderItem");
            orderItems.add(orderItem);
            totalNum+=orderItem.getNum();
            totalMoney+=orderItem.getMoney();
        }
        //扣减库存
        boolean flag = skuService.koujianKucun(orderItems);
        if (!flag){
            throw  new RuntimeException("库存扣减失败！");
        }

        try {
            //组装订单数据
            order.setTotalNum(totalNum);
            order.setTotalMoney(totalMoney);
            order.setPayMoney(getMyPreMoney(username));

            order.setPostFee(0);

            order.setPreMoney(order.getTotalMoney()-order.getPayMoney()+order.getPostFee());
            order.setCreateTime(new Date());
            order.setUpdateTime(order.getCreateTime());

            order.setUsername(username);
            order.setSourceType("1");//来源 web
            order.setOrderStatus("0");//订单状态 待支付
            order.setPayStatus("0");//支付状态 未付款


            order.setConsignStatus("0");//发货状态
            order.setIsDelete("0");//是否删除 未删除


            order.setId(idWorker.nextId()+"");
            orderMapper.insert(order);

            for (OrderItem orderItem : orderItems) {

                orderItem.setId(idWorker.nextId()+"");
                double rate = orderItem.getMoney()/order.getTotalMoney();
                int onePreMoney =(int) (rate*order.getPreMoney());


                orderItem.setPayMoney(orderItem.getMoney()-onePreMoney);

                orderItem.setOrderId(order.getId());
                orderItem.setIsReturn("0");

                orderItemMapper.insert(orderItem);
            }
            //System.out.println(1/0);
            ArrayList<Map> newCarts = new ArrayList<>();
            //清理购物车
            for (Map map : cart) {
                if (!(Boolean)map.get("checked")) {
                    newCarts.add(map);
                }
            }
            redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,newCarts);
        } catch (Exception e) {
            e.printStackTrace();
            //需要发消息

            rabbitTemplate.convertAndSend("","queue.skuback",JSONObject.toJSONString(orderItems));

            throw e;

        }

        HashMap<String, Object> hashMap = new HashMap<>();

        hashMap.put("ordersn",order.getId());
        hashMap.put("paymoney",order.getPreMoney());

        return hashMap;
    }
}
